package com.yanx.framework.redis;

import cn.hutool.extra.spring.SpringUtil;
import com.yanx.common.exception.BusinessException;

import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * Redis缓存管理接口
 *
 * @author gotanks
 * @create 2022/3/16
 */
public interface RedisCacheManager<T> {

    RedisCache redisCache = SpringUtil.getBean(RedisCache.class);

    /**
     * 缓存key的组成部分，可用入参拼成一个key，如果不覆盖，则取入参第一个参数为key
     *
     * @param keyParts key组成部分
     * @return
     */
    default String key(Object... keyParts) {
        if (keyParts == null || keyParts.length == 0) {
            throw new BusinessException("cache key is null !");
        }
        return keyParts[0].toString();
    }

    /**
     * 缓存超时时间
     *
     * @return
     */
    default Integer timeout() {
        return null;
    }

    /**
     * 缓存超时单位，默认秒
     *
     * @return
     */
    default TimeUnit timeUnit() {
        return TimeUnit.SECONDS;
    }

    /**
     * 设置缓存
     *
     * @param keyParts key组成部分
     * @param cacheObj 缓存的对象
     */
    default void set(Object[] keyParts, T cacheObj) {
        if (keyParts == null) {
            keyParts = new Object[0];
        }
        if (this.timeout() == null) {
            this.redisCache.setCacheObject(this.key(keyParts), cacheObj);
        } else {
            this.redisCache.setCacheObject(this.key(keyParts), cacheObj, this.timeout(), this.timeUnit());
        }
    }

    /**
     * 读取缓存
     *
     * @param keyParts key组成部分
     * @return
     */
    default T get(Object... keyParts) {
        if (keyParts == null) {
            keyParts = new Object[0];
        }
        return this.redisCache.getCacheObject(this.key(keyParts));
    }

    /**
     * 读取缓存，如果为空，则执行方法获取对象并设置
     *
     * @param keyParts        key组成部分
     * @param defaultSupplier 获取对象的方法
     * @return
     */
    default T get(Object[] keyParts, Supplier<T> defaultSupplier) {
        if (keyParts == null) {
            keyParts = new Object[0];
        }
        T t = this.get(keyParts);
        if (t == null) {
            t = defaultSupplier.get();
            this.set(keyParts, t);
        }
        return t;
    }

    /**
     * 删除缓存
     *
     * @param keyParts key组成部分
     */
    default void delete(Object... keyParts) {
        if (keyParts == null) {
            keyParts = new Object[0];
        }
        this.redisCache.deleteObject(this.key(keyParts));
    }

    /**
     * 删除所有
     */
    default void deleteAll() {
        String key = this.key().replace("{}", "*");
        Collection<String> keys = this.redisCache.keys(key);
        this.redisCache.deleteObject(keys);
    }

}
